﻿/*
 * Created by qianbo on 2017/10/25.
 */
'use strict';

class m{
    constructor(obj){
        this.obj = obj;
        this.next = null;
        this.prior = null;
    }
}

class linklist{
    constructor (num) {
        this.obj_num  = 0;
        this.first = null;
        this.last = null;
        this.obj_num_max = num;
    }


    // remove a item from its list
    remove() {
        if(this.first.next!=null){
            this.first = this.first.next;
            this.first.prior = null; 
        }
    }


    // remove a item from its list and place at the end.
    append(obj) {
        // 把item的节点，插入到list的后面去
        var li = new m(obj);
        if(this.obj_num >=this.obj_num_max){
            this.remove();
            this.obj_num -- ;
        }
        if(this.obj_num == 0){ //是第一个
            this.first = li;
            li.prior = null;
            li.next = null;
            this.last = li;
        }else{
            this.last.next = li;
            li.prior = this.last;
            this.last = li;
        }
        this.obj_num++;
    }
    find(vkey,vvalue,fields){
        var link = this.first;
        while(link !=null){
            var obj = link.obj;
            if(obj!=null && obj[vkey]!=null){
                if(obj[vkey] == vvalue){
                    if(fields == null)
                        return obj;
                    var fs = fields.split(',');
                    var retobj = {};
                    for(var i = 0 ;i< fs.length;i++){
                        let ff = fs[i];
                        if(obj[ff]!=null){
                            retobj[ff] = obj[ff];
                        }
                    }
                    return retobj;
                }
            }
            link = link.next;
        }
        return null;
    }

    find_all_except(field){
        var ret = [];
        var link = this.last;
        while(link !=null){
            var obj = link.obj;
            if(obj!=null ){
                if(field == null)
                    ret.push(obj);
                else{
                    var inobj = {};
                    for(var key in obj){
                        if(key!=field){
                            inobj[key] = obj[key];
                        }
                    }
                    ret.push(inobj);
                }
            }
            link = link.prior;
        }
        return ret;
    }

}

// var x = new linklist(5);
// x.append({id:1,x:10,y:10});
// x.append({id:2,x:10,y:10});
// x.append({id:3,x:10,y:10});
// x.append({id:4,x:20,y:10});
// x.append({id:5,x:20,y:10});
//x.append({id:6,x:20,y:10});
//var y = x.find("id",4,"x");
// var z = x.find_all_except("x");
////console.log(x);
// console.log(z);

class cache{
    constructor(){
        this.map = new Map();
        this.num = 10; //默认10条缓存
    }
    cache_set_every_max(num){
        this.num = num;
    }
    //key->values not key->value
    cache_insert(key, obj, cb){
        var inobj = this.map.get(key);
        if(inobj == null)
            inobj = new linklist(this.num);
        inobj.append(obj);
        this.map.set(key,inobj);
        if(cb!=null)
            cb();
    }

      //fields 想要的字段 cache_get_one(key,'id','20',fields, cb)
    cache_get_one(key,vkey,vvalue,fields,cb){
        var inobj = this.map.get(key);
        if(inobj == null)
            return null;
        var retobj = inobj.find(vkey,vvalue,fields);
        if(cb == null)
            return retobj;
        if(retobj == null)
            cb(-1,null);
        else
            cb(1, retobj);
        //return retobj;
    }

    //排除字段except_field
    cache_get_value(key,except_field,cb){
        var inobj = this.map.get(key);
        if(inobj == null)
            return null;
        var retobj = inobj.find_all_except(except_field);
        if(cb == null)
            return retobj;
        if(retobj == null)
            cb(-1,null);
        else
            cb(1, retobj);
    }
}

module.exports = cache;


///以下是测试
/*
var mycache = new cache();
mycache.cache_set_every_max(5);
mycache.cache_insert(1,{id:1,iid:111,y :"I am qianbo1"},null);
mycache.cache_insert(1,{id:2,iid:111,y :"I am qianbo2"},null);
mycache.cache_insert(1,{id:3,iid:111,y :"I am qianbo3"},null);
mycache.cache_insert(1,{id:4,iid:111,y :"I am qianbo4"},null);
mycache.cache_insert(1,{id:5,iid:111,y :"I am qianbo5"},null);
mycache.cache_insert(1,{id:6,iid:111,y :"I am qianbo5"},null);
mycache.cache_insert(1,{id:7,iid:111,y :"I am qianbo5"},null);
mycache.cache_insert(1,{id:8,iid:111,y :"I am qianbo5"},null);
mycache.cache_insert(1,{id:9,iid:111,y :"I am qianbo5"},null);
mycache.cache_insert(1,{id:10,iid:111,y :"I am qianbo5"},null);
mycache.cache_insert(2,{id:1,iid:111,y :"I am qianboxx"},null);

var objx = mycache.cache_get_one(1,"id",7,null,null);

var objy = mycache.cache_get_value(1,"iid");
console.log(objy);
*/
